﻿using System;
using System.Collections;
using System.ComponentModel;
using System.Linq;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.Design;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace SCS.Web.UI.WebControls
{
    /// <summary>
    /// Contains the <see cref="HierListItemBinding"/> definitions.
    /// </summary>
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    public class HierListItemBindingCollection : StateManagedCollection
    {
        // Fields
        private HierListItemBinding _defaultBinding;
        private HierList _owner;
        private static readonly Type[] knownTypes = new Type[] { typeof(HierListItemBinding) };

        // Methods
        private HierListItemBindingCollection()
        {
        }

        internal HierListItemBindingCollection(HierList owner)
        {
            this._owner = owner;
        }

        /// <summary>
        /// Adds the <see cref="HierListItemBinding"/> to the collection.
        /// </summary>
        /// <param name="binding">The binding.</param>
        /// <returns></returns>
        public int Add(HierListItemBinding binding)
        {
            return ((IList)this).Add(binding);
        }

        /// <summary>
        /// Determines whether the <see cref="HierListItemBinding"/> exists in the collection.
        /// </summary>
        /// <param name="binding">The binding.</param>
        /// <returns>
        /// 	<c>true</c> if has the specified binding; otherwise, <c>false</c>.
        /// </returns>
        public bool Contains(HierListItemBinding binding)
        {
            return ((IList)this).Contains(binding);
        }

        /// <summary>
        /// Copies an array of <see cref="HierListItemBinding"/> objects to the collection starting at the given index.
        /// </summary>
        /// <param name="array">The array.</param>
        /// <param name="index">The index.</param>
        public void CopyTo(HierListItemBinding[] array, int index)
        {
            this.CopyTo(array, index);
        }

        /// <summary>
        /// When overridden in a derived class, creates an instance of a class that implements <see cref="T:System.Web.UI.IStateManager"/>. The type of object created is based on the specified member of the collection returned by the <see cref="M:System.Web.UI.StateManagedCollection.GetKnownTypes"/> method.
        /// </summary>
        /// <param name="index">The index, from the ordered list of types returned by <see cref="M:System.Web.UI.StateManagedCollection.GetKnownTypes"/>, of the type of <see cref="T:System.Web.UI.IStateManager"/> to create.</param>
        /// <returns>
        /// An instance of a class derived from <see cref="T:System.Web.UI.IStateManager"/>, according to the <paramref name="index"/> provided.
        /// </returns>
        /// <exception cref="T:System.InvalidOperationException">In all cases when not overridden in a derived class.</exception>
        protected override object CreateKnownType(int index)
        {
            return new HierListItemBinding();
        }

        private void FindDefaultBinding()
        {
            this._defaultBinding = null;
            foreach (HierListItemBinding binding in this)
            {
                if ((binding.Depth == -1) && (binding.DataMember.Length == 0))
                {
                    this._defaultBinding = binding;
                    break;
                }
            }
        }

        /// <summary>
        /// Gets the binding for a data member at a given depth.
        /// </summary>
        /// <param name="dataMember">The data member.</param>
        /// <param name="depth">The depth.</param>
        /// <returns>A <see cref="HierListItemBinding"/> instance.</returns>
        internal HierListItemBinding GetBinding(string dataMember, int depth)
        {
            HierListItemBinding binding = null;
            int num = 0;
            if ((dataMember != null) && (dataMember.Length == 0))
            {
                dataMember = null;
            }
            foreach (HierListItemBinding binding2 in this)
            {
                if (binding2.Depth == depth)
                {
                    if (string.Equals(binding2.DataMember, dataMember, StringComparison.CurrentCultureIgnoreCase))
                    {
                        return binding2;
                    }
                    if ((num < 1) && (binding2.DataMember.Length == 0))
                    {
                        binding = binding2;
                        num = 1;
                    }
                    continue;
                }
                if ((string.Equals(binding2.DataMember, dataMember, StringComparison.CurrentCultureIgnoreCase) && (num < 2)) && (binding2.Depth == -1))
                {
                    binding = binding2;
                    num = 2;
                }
            }
            if ((binding != null) || (this._defaultBinding == null))
            {
                return binding;
            }
            if ((this._defaultBinding.Depth != -1) || (this._defaultBinding.DataMember.Length != 0))
            {
                this.FindDefaultBinding();
            }
            return this._defaultBinding;
        }

        /// <summary>
        /// When overridden in a derived class, gets an array of <see cref="T:System.Web.UI.IStateManager"/> types that the <see cref="T:System.Web.UI.StateManagedCollection"/> collection can contain.
        /// </summary>
        /// <returns>
        /// An ordered array of <see cref="T:System.Type"/> objects that identify the types of <see cref="T:System.Web.UI.IStateManager"/> objects the collection can contain. The default implementation returns null.
        /// </returns>
        protected override Type[] GetKnownTypes()
        {
            return knownTypes;
        }

        /// <summary>
        /// Returns the index of the given <see cref="HierListItemBinding"/>.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns>The binding index in the collection.</returns>
        public int IndexOf(HierListItemBinding value)
        {
            return ((IList)this).IndexOf(value);
        }

        /// <summary>
        /// Inserts the <see cref="HierListItemBinding"/> at the specified index.
        /// </summary>
        /// <param name="index">The index.</param>
        /// <param name="binding">The binding.</param>
        public void Insert(int index, HierListItemBinding binding)
        {
            ((IList)this).Insert(index, binding);
        }

        /// <summary>
        /// When overridden in a derived class, performs additional work before the <see cref="M:System.Web.UI.StateManagedCollection.Clear"/> method removes all items from the collection.
        /// </summary>
        protected override void OnClear()
        {
            this._defaultBinding = null;
        }

        /// <summary>
        /// When overridden in a derived class, performs additional work after the <see cref="M:System.Web.UI.StateManagedCollection.System.Collections.IList.Remove(System.Object)"/> or <see cref="M:System.Web.UI.StateManagedCollection.System.Collections.IList.RemoveAt(System.Int32)"/> method removes the specified item from the collection.
        /// </summary>
        /// <param name="index">The zero-based index of the item to remove, which is used when <see cref="M:System.Web.UI.StateManagedCollection.System.Collections.IList.RemoveAt(System.Int32)"/> is called.</param>
        /// <param name="value">The object removed from the <see cref="T:System.Web.UI.StateManagedCollection"/>, which is used when <see cref="M:System.Web.UI.StateManagedCollection.System.Collections.IList.Remove(System.Object)"/> is called.</param>
        protected override void OnRemoveComplete(int index, object value)
        {
            if (value == this._defaultBinding)
            {
                this.FindDefaultBinding();
            }
        }

        /// <summary>
        /// When overridden in a derived class, validates an element of the <see cref="T:System.Web.UI.StateManagedCollection"/> collection.
        /// </summary>
        /// <param name="value">The <see cref="T:System.Web.UI.IStateManager"/> to validate.</param>
        /// <exception cref="T:System.ArgumentNullException">
        /// 	<paramref name="value"/> is null.</exception>
        protected override void OnValidate(object value)
        {
            base.OnValidate(value);
            HierListItemBinding binding = value as HierListItemBinding;
            if (((binding != null) && (binding.DataMember.Length == 0)) && (binding.Depth == -1))
            {
                this._defaultBinding = binding;
            }
        }

        /// <summary>
        /// Removes the specified binding.
        /// </summary>
        /// <param name="binding">The binding.</param>
        public void Remove(HierListItemBinding binding)
        {
            ((IList)this).Remove(binding);
        }

        /// <summary>
        /// Removes the <see cref="T:System.Collections.IList"/> item at the specified index.
        /// </summary>
        /// <param name="index">The zero-based index of the item to remove.</param>
        /// <exception cref="T:System.ArgumentOutOfRangeException">
        /// 	<paramref name="index"/> is not a valid index in the <see cref="T:System.Collections.IList"/>. </exception>
        /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.IList"/> is read-only.-or- The <see cref="T:System.Collections.IList"/> has a fixed size. </exception>
        public void RemoveAt(int index)
        {
            ((IList)this).RemoveAt(index);
        }

        /// <summary>
        /// When overridden in a derived class, instructs an object contained by the collection to record its entire state to view state, rather than recording only change information.
        /// </summary>
        /// <param name="o">The <see cref="T:System.Web.UI.IStateManager"/> that should serialize itself completely.</param>
        protected override void SetDirtyObject(object o)
        {
            if (o is HierListItemBinding)
            {
                ((HierListItemBinding)o).SetDirty();
            }
        }

        /// <summary>
        /// Gets or sets the <see cref="SCS.Web.UI.WebControls.HierListItemBinding"/> with the specified index.
        /// </summary>
        /// <value></value>
        public HierListItemBinding this[int index]
        {
            get
            {
                return (HierListItemBinding)this[index];
            }
            set
            {
                this[index] = value;
            }
        }
    }
}
